package client

import (
	"context"
	"time"

	"gitee.com/xuxinzhi2206/corehub/nacos"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials/insecure"

	"gitee.com/enjoy_5/enjoy-wallet/consts"
	"gitee.com/enjoy_5/enjoy-wallet/proto/address"
	wallet "gitee.com/enjoy_5/enjoy-wallet/proto/wallet"
)

// 创建grpc客户端连接
func clientWallet(ctx context.Context, hand func(c wallet.WalletClient) error) error {
	service, err := nacos.FindHealthService(consts.SERVICE_NAME, consts.GROUP_NAME)
	if err != nil {
		return err
	}
	conn, err := grpc.NewClient(service, grpc.WithTransportCredentials(insecure.NewCredentials()))
	if err != nil {
		return err
	}
	defer conn.Close()

	// Contact the server and print out its response.
	_, cancel := context.WithTimeout(ctx, time.Second)
	defer cancel()

	c := wallet.NewWalletClient(conn)

	return hand(c)
}

func clientAddress(ctx context.Context, hand func(c address.AddressClient) error) error {
	service, err := nacos.FindHealthService(consts.SERVICE_NAME, consts.GROUP_NAME)
	if err != nil {
		return err
	}
	conn, err := grpc.NewClient(service, grpc.WithTransportCredentials(insecure.NewCredentials()))
	if err != nil {
		return err
	}
	defer conn.Close()

	// Contact the server and print out its response.
	_, cancel := context.WithTimeout(ctx, time.Second)
	defer cancel()

	c := address.NewAddressClient(conn)

	return hand(c)
}

func FirstUserBalance(ctx context.Context, in *wallet.UserBalanceInfo) (info *wallet.UserBalanceInfo, err error) {
	err = clientWallet(ctx, func(c wallet.WalletClient) error {
		balance, err := c.FirstUserBalance(ctx, &wallet.FirstUserBalanceRequest{In: in})
		if err != nil {
			return err
		}

		info = balance.UserBalanceInfo
		return err
	})
	return
}

func CreateRechargeRecord(ctx context.Context, in *wallet.RechargeRecordInfo) (info *wallet.RechargeRecordDescription, err error) {
	err = clientWallet(ctx, func(c wallet.WalletClient) error {
		balance, err := c.CreateRechargeRecord(ctx, &wallet.CreateRechargeRecordRequest{In: in})
		if err != nil {
			return err
		}

		info = balance.RechargeRecordDescription
		return err
	})
	return
}

func CreateUserConsumptionDetails(ctx context.Context, in *wallet.UserConsumptionDetailsInfo) (info *wallet.UserConsumptionDetailsInfo, err error) {
	err = clientWallet(ctx, func(c wallet.WalletClient) error {
		balance, err := c.CreateUserConsumptionDetails(ctx, &wallet.CreateUserConsumptionDetailsRequest{In: in})
		if err != nil {
			return err
		}

		info = balance.UserConsumptionDetailsInfo
		return err
	})
	return
}

func SearchUserConsumptionDetails(ctx context.Context, offset, limit int64) (info *wallet.SearchUserConsumptionDetailsResponse, err error) {
	err = clientWallet(ctx, func(c wallet.WalletClient) error {
		balance, err := c.SearchUserConsumptionDetails(ctx, &wallet.SearchUserConsumptionDetailsRequest{
			Offset: offset,
			Limit:  limit,
		})
		if err != nil {
			return err
		}

		info = &wallet.SearchUserConsumptionDetailsResponse{
			Infos: balance.Infos,
			Total: balance.Total,
		}
		return err
	})
	return
}

func CreateAddress(ctx context.Context, in *address.AddressInfo) (info *address.AddressInfo, err error) {
	err = clientAddress(ctx, func(c address.AddressClient) error {
		balance, err := c.CreateAddress(ctx, &address.CreateAddressRequest{In: in})
		if err != nil {
			return err
		}

		info = balance.Info
		return err
	})
	return
}

func UpdateAddress(ctx context.Context, in *address.AddressInfo) (info *address.AddressInfo, err error) {
	err = clientAddress(ctx, func(c address.AddressClient) error {
		balance, err := c.UpdateAddress(ctx, &address.UpdateAddressRequest{In: in})
		if err != nil {
			return err
		}

		info = balance.Info
		return err
	})
	return
}

func DeleteAddress(ctx context.Context, userid int64) (info *address.DeleteAddressResponse, err error) {
	err = clientAddress(ctx, func(c address.AddressClient) error {
		_, err := c.DeleteAddress(ctx, &address.DeleteAddressRequest{UserID: userid})
		if err != nil {
			return err
		}

		info = &address.DeleteAddressResponse{}
		return err
	})
	return
}

func SearchAddress(ctx context.Context, offset, limit int64) (info *address.SearchAddressResponse, err error) {
	err = clientAddress(ctx, func(c address.AddressClient) error {
		balance, err := c.SearchAddress(ctx, &address.SearchAddressRequest{
			Offset: offset,
			Limit:  limit,
		})
		if err != nil {
			return err
		}

		info = &address.SearchAddressResponse{
			Infos: balance.Infos,
			Total: balance.Total,
		}
		return err
	})
	return
}
